package xml;

import java.util.ArrayList;
import java.util.HashMap;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;


/*
 * this is the SAX visitor which been called during this index building when
 * the SAX parser enters or leave a ode 
 */
public class IdToRouteIndexHandler extends DefaultHandler
{
	private ArrayList<Integer>_currentIdPath = new ArrayList<Integer>();
	private int _nodeId = 0;
	
	/*
	 * will hold the mapping between node's id to the route's id
	 */
	//private HashMap<Integer,Integer> _nodeIdToRoutIdMap;
	
	private ArrayList<Integer> _nodeIdToRoutIdMapping;
	
	/*
	 *  will hold the mapping between serialized route to the route's index 
	 */
	private ArrayList<ArrayList<Integer>> _routeIdToSerializedRouteMapping;
	
	/*
	 * will hold the mapping between the labelId to the label's name
	 */
	private ArrayList<String> _labelIdToLabelMapping;
	
	private HashMap<String,Integer> _labelToLabelIdMap;
	
	private HashMap<ArrayList<Integer>,Integer> _serializedRouteToRouteIdMap;
	
	public IdToRouteIndexHandler( 	/*HashMap<Integer,Integer> nodeIdToRoutIdMap,*/
									ArrayList<Integer> nodeIdToRoutIdMapping,
									ArrayList<ArrayList<Integer>> routeIdToSerializedRouteMapping,
									ArrayList<String> labelIdToLabelMapping)
	{
		_nodeIdToRoutIdMapping = nodeIdToRoutIdMapping;
		_routeIdToSerializedRouteMapping = routeIdToSerializedRouteMapping;
		_labelIdToLabelMapping = labelIdToLabelMapping;
		
		//helpers DAST for not making any duplications. if we have some data already, make reference to it
		_labelToLabelIdMap = new HashMap<String, Integer>();
		_serializedRouteToRouteIdMap = new HashMap<ArrayList<Integer>, Integer>();
	}
	
	public void startElement(String uri, String localName, String qName, Attributes attributes)  {
 		
		
		//check if we have this label in storage already
		if (!_labelToLabelIdMap.containsKey(qName))
		{
			int labelId = _labelToLabelIdMap.size();
			_labelToLabelIdMap.put(qName, labelId);
			_labelIdToLabelMapping.add(qName);
			_currentIdPath.add(labelId);
		}
		else
		{
			_currentIdPath.add(_labelToLabelIdMap.get(qName));
		}
		
		//connect current node with current path
		int routeId;
		
		//check if we have this path in storage already
		if (!_serializedRouteToRouteIdMap.containsKey(_currentIdPath))
		{
			routeId = _serializedRouteToRouteIdMap.size();
			_serializedRouteToRouteIdMap.put(new ArrayList<Integer>(_currentIdPath), routeId);
			_routeIdToSerializedRouteMapping.add(new ArrayList<Integer>(_currentIdPath));
		}
		else
		{
			routeId = _serializedRouteToRouteIdMap.get(new ArrayList<Integer>(_currentIdPath));
		}
		
		//_nodeIdToRoutIdMap.ensureCapacity(_nodeId+1);
		_nodeIdToRoutIdMapping.add(routeId);
		//_nodeIdToRoutIdMap.put(_nodeId,routeId);
		_nodeId++;
	}
 
	public void endElement(String uri, String localName,
		String qName) throws SAXException {
		
		//trim the last id from the current path
		_currentIdPath.remove(_currentIdPath.size()-1);
 
	}
	
	
}